package rpc.frame.client.discovery.zk;

import org.I0Itec.zkclient.IZkChildListener;
import org.I0Itec.zkclient.ZkClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import rpc.frame.client.config.RpcClientConfiguration;
import rpc.frame.core.cache.ServiceProviderCache;
import rpc.frame.core.provider.ServiceProvider;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * zk client 工具类
 */
@Component
public class ClientZKit {

    @Resource
    private RpcClientConfiguration configuration;

    @Autowired
    private ZkClient zkClient;

    @Resource
    private ServiceProviderCache cache;//缓存容器

    /**
     * 获取全量的服务接口
     * @return
     */
    public List<String> getServiceList(){
        String path=configuration.getRoot();
        List<String> children = zkClient.getChildren(path);
        return children;
    }


    /**
     * 获取接口下全部的服务提供者
     * @param serviceName
     * @return
     */
    public List<ServiceProvider> getServiceInfos(String serviceName){
        String path=configuration.getRoot()+"/"+serviceName;
        List<String> children = zkClient.getChildren(path);
        List<ServiceProvider> serviceProviders = convertToProviderService(serviceName,children);
        return serviceProviders;
    }


    /**
     * 服务订阅接口
     * @param serviceName
     */
    public void subscribeZkEvent(String serviceName){
        String path = configuration.getRoot() + "/" + serviceName;
        zkClient.subscribeChildChanges(path, new IZkChildListener() {
            @Override
            public void handleChildChange(String s, List<String> list) throws Exception {
                //判断节点信息是否为空
                if(!CollectionUtils.isEmpty(list)){
                    List<ServiceProvider> serviceProviders = convertToProviderService(serviceName, list);
                    cache.update(serviceName,serviceProviders);
                }
            }
        });

    }

    /**
     * 将 zk 存储的字符串转换成对象
     * @param serviceName
     * @param list
     * @return
     */
    private static  List<ServiceProvider> convertToProviderService(String serviceName,List<String> list){
        if(list==null){
            return null;
        }
        List<ServiceProvider> providers = list.stream().map(v -> {
            String[] split = v.split(":");
            return ServiceProvider.builder()
                    .serverName(serviceName)
                    .serverIp(split[0])
                    .rpcPort(Integer.parseInt(split[1]))
                    .build();
        }).collect(Collectors.toList());
        return providers;
    }

}
